/*************************************************************************
	UKag Dynamic Effect Handler
	move,rotate,scale,shake,jump,fade,etc
*************************************************************************/

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class UKagActionHandler : MonoBehaviour
{
	private List<string> ActionList = new List<string>();
	protected internal UKagSystem m_System = null;

	public bool HasAction(string key)
	{
		return ActionList.IndexOf(key) >= 0;
	}
	
	public void WaitAction(UKagConductor conductor, UTVPLayer layerObj, string type, bool canSkip)
	{
		UTVPTweener.TWEEN_TYPE actionType = UTVPTweener.TWEEN_TYPE.All;
		if (!string.IsNullOrEmpty(type))
			actionType = (UTVPTweener.TWEEN_TYPE)Enum.Parse(typeof(UTVPTweener.TWEEN_TYPE), type, true);

		string key = null;
		if (layerObj != null)
		{
			if (actionType != UTVPTweener.TWEEN_TYPE.All)
			{
				key = layerObj.name + "_" + type;
				if (ActionList.IndexOf(key) >= 0)
					conductor.WaitTrigger("_action_" + key, canSkip);
			}
			else
			{
				key = layerObj.name + "_";
				for (int i=0; i<ActionList.Count; i++)
					if (ActionList[i].StartsWith(key))
						conductor.WaitTrigger("_action_" + ActionList[i], canSkip);
			}
		}
		else
		{
			if (actionType != UTVPTweener.TWEEN_TYPE.All)
			{
				key = "_" + type;
				for (int i=0; i<ActionList.Count; i++)
					if (ActionList[i].EndsWith(key))
						conductor.WaitTrigger("_action_" + ActionList[i], canSkip);
			}
			else
			{
				for (int i=0; i<ActionList.Count; i++)
					conductor.WaitTrigger("_action_" + ActionList[i], canSkip);
			}
		}
	}
	
	private List<Vector4> vector3ConvertTemp = new List<Vector4>();
	private char[] pathSeparator= {' ', ',', '(', ')'};
	public Vector4[] Str2Vector3List(string strData, float x, float y, float z)
	{
		string[] values = strData.Split(pathSeparator);
		int p = 0, valueLength = values.Length;
		vector3ConvertTemp.Clear();
		while ( p < valueLength)
		{
			while (p < values.Length && String.IsNullOrEmpty(values[p]))
				p++;
			if (p < values.Length)
				m_System.Str2Number(values[p++], ref x);
			while (p < values.Length && String.IsNullOrEmpty(values[p]))
				p++;
			if (p < values.Length)
				m_System.Str2Number(values[p++], ref y);
			while (p < values.Length && String.IsNullOrEmpty(values[p]))
				p++;
			if (p < values.Length)
			{
				m_System.Str2Number(values[p++], ref z);
				vector3ConvertTemp.Add(new Vector4(x, y, z, 0));
			}
		}
		return vector3ConvertTemp.ToArray();
	}
	
	public Vector4[] Str2Vector3List2D(string strData, float x, float y, float z)
	{
		string[] values = strData.Split(pathSeparator);
		int p = 0, valueLength = values.Length;
		vector3ConvertTemp.Clear();
		while ( p < valueLength)
		{
			while (p < values.Length && String.IsNullOrEmpty(values[p]))
				p++;
			if (p < values.Length)
				m_System.Str2Number(values[p++], ref x);
			while (p < values.Length && String.IsNullOrEmpty(values[p]))
				p++;
			if (p < values.Length)
			{
				m_System.Str2Number(values[p++], ref y);
				vector3ConvertTemp.Add(new Vector4(x, y, z, 0));
			}
		}
		return vector3ConvertTemp.ToArray();
	}

	public void StopAction(string actionName)
	{
		if (string.IsNullOrEmpty(actionName))
		{
			StopAction(null, UTVPTweener.TWEEN_TYPE.All);
		}
		else
		{
			string layerName = actionName.Substring(1);
			UTVPLayer layer = m_System.GetLayerByName(layerName);
			StopAction(layer, UTVPTweener.TWEEN_TYPE.All);
		}
	}

	public void StopAction(UTVPLayer target, string type)
	{
		UTVPTweener.TWEEN_TYPE actionType = UTVPTweener.TWEEN_TYPE.All;
		if (!string.IsNullOrEmpty(type))
			actionType = (UTVPTweener.TWEEN_TYPE)Enum.Parse(typeof(UTVPTweener.TWEEN_TYPE), type, true);

		StopAction(target, actionType);
	}
	public void StopAction(UTVPLayer target, UTVPTweener.TWEEN_TYPE type)
	{
		int i = 0;
		switch (type)
		{
		case UTVPTweener.TWEEN_TYPE.Position:
			if (target != null)
			{
				target.Tweener.EndPositionTweener();
			}
			else
			{
				for (i=0; i<m_System.FgLayers.Length; i++)
					m_System.FgLayers[i].Tweener.EndPositionTweener();
				for (i=0; i<m_System.MsgLayers.Length; i++)
					m_System.MsgLayers[i].Frame.Tweener.EndPositionTweener();
			}
			break;
		case UTVPTweener.TWEEN_TYPE.Rotation:
			if (target != null)
			{
				target.Tweener.EndRotationTweener();
			}
			else
			{
				for (i=0; i<m_System.FgLayers.Length; i++)
					m_System.FgLayers[i].Tweener.EndRotationTweener();
				for (i=0; i<m_System.MsgLayers.Length; i++)
					m_System.MsgLayers[i].Frame.Tweener.EndRotationTweener();
			}
			break;
		case UTVPTweener.TWEEN_TYPE.Scale:
			if (target != null)
			{
				target.Tweener.EndScaleTweener();
			}
			else
			{
				for (i=0; i<m_System.FgLayers.Length; i++)
					m_System.FgLayers[i].Tweener.EndScaleTweener();
				for (i=0; i<m_System.MsgLayers.Length; i++)
					m_System.MsgLayers[i].Frame.Tweener.EndScaleTweener();
			}
			break;
		case UTVPTweener.TWEEN_TYPE.Color:
			if (target != null)
			{
				target.Tweener.EndColorTweener();
			}
			else
			{
				for (i=0; i<m_System.FgLayers.Length; i++)
					m_System.FgLayers[i].Tweener.EndColorTweener();
				for (i=0; i<m_System.MsgLayers.Length; i++)
					m_System.MsgLayers[i].Frame.Tweener.EndColorTweener();
			}
			break;
		default:
			if (target != null)
			{
				target.Tweener.EndAllTweener();
			}
			else
			{
				for (i=0; i<m_System.FgLayers.Length; i++)
					m_System.FgLayers[i].Tweener.EndAllTweener();
				for (i=0; i<m_System.MsgLayers.Length; i++)
					m_System.MsgLayers[i].Frame.Tweener.EndAllTweener();
			}
			break;
		}

		if (target != null)
		{
			if (type != UTVPTweener.TWEEN_TYPE.All)
			{
				ActionList.Remove(target.name + "_" + type.ToString());
			}
			else
			{
				string key = target.name + "_";
				for (i = ActionList.Count - 1; i >= 0; i--)
					if (ActionList[i].StartsWith(key))
						ActionList.RemoveAt(i);
			}
		}
		else
		{
			if (type != UTVPTweener.TWEEN_TYPE.All)
			{
				string key = "_" + type.ToString();
				for (i = ActionList.Count - 1; i >= 0; i--)
					if (ActionList[i].EndsWith(key))
						ActionList.RemoveAt(i);
			}
			else
			{
				ActionList.Clear();
			}
		}
	}

	public void PauseAction(UTVPLayer target)
	{
		if (target != null)
		{
			target.Tweener.Pause = true;
		}
		else
		{
			for (int i=0; i<m_System.FgLayers.Length; i++)
				m_System.FgLayers[i].Tweener.Pause = true;
			for (int i=0; i<m_System.MsgLayers.Length; i++)
				m_System.MsgLayers[i].Frame.Tweener.Pause = true;
		}
	}
	
	public void ResumeAction(UTVPLayer target)
	{
		if (target != null)
		{
			target.Tweener.Pause = false;
		}
		else
		{
			for (int i=0; i<m_System.FgLayers.Length; i++)
				m_System.FgLayers[i].Tweener.Pause = false;
			for (int i=0; i<m_System.MsgLayers.Length; i++)
				m_System.MsgLayers[i].Frame.Tweener.Pause = false;
		}
	}
	
	public void StartAction(UTVPLayer target, Dictionary<string, string> paramDic)
	{
		int time = 2000;
		Str2Number(paramDic, "time", ref time);

		UTVPTweener.EASE_TYPE easeType = UTVPTweener.EASE_TYPE.Linear;
		if (paramDic.ContainsKey("easetype"))
			easeType = (UTVPTweener.EASE_TYPE)Enum.Parse(typeof(UTVPTweener.EASE_TYPE), paramDic["easetype"], true);

		if (paramDic.ContainsKey("path"))
		{
			Vector4[] pathVec = Str2Vector3List2D(paramDic["path"], target.Left, target.Top, 0);
			UTVPTweener.TWEEN_TYPE type = UTVPTweener.TWEEN_TYPE.Position;
			//if (paramDic.ContainsKey("type"))
			//	type = (UTVPTweener.TWEEN_TYPE)Enum.Parse(typeof(UTVPTweener.TWEEN_TYPE), paramDic["type"], true);
			if (pathVec.Length > 1)
			{
				float[] timeList = new float[pathVec.Length];
				for (int i=0; i<pathVec.Length; i++)
				{
					timeList[i] = pathVec[i].z / 1000.0f;
					pathVec[i] = target.GetLocalPosition((int)pathVec[i].x, (int)pathVec[i].y);
				}
				target.Tweener.TweenPosition(pathVec, easeType, timeList);
			}
			else if (pathVec.Length == 1)
			{
				Vector3 pos = target.GetLocalPosition((int)pathVec[0].x, (int)pathVec[0].y);
				target.Tweener.TweenPosition(pos, easeType, time / 1000.0f);
			}
			ActionList.Add(target.Tweener.GetTweenName(type));
		}

		if (paramDic.ContainsKey("x") || paramDic.ContainsKey("y"))
		{
			int x = target.Left;
			Str2Number(paramDic, "x", ref x);
			int y = target.Top;
			Str2Number(paramDic, "y", ref y);
			Vector3 pos = target.GetLocalPosition(x, y);

			target.Tweener.TweenPosition(pos, easeType, time / 1000.0f);
			ActionList.Add(target.Tweener.GetTweenName(UTVPTweener.TWEEN_TYPE.Position));
		}
		
		if (paramDic.ContainsKey("color"))
		{
			Color color = UTVPUtil.StrToColor(paramDic["color"]);
			target.Tweener.TweenColor(color, easeType, time / 1000.0f);
			ActionList.Add(target.Tweener.GetTweenName(UTVPTweener.TWEEN_TYPE.Color));
		}
		else if (paramDic.ContainsKey("alpha"))
		{
			Color color = target.Color;
			int alphaInt = (int)(color.a * 255);
			if (Str2Number(paramDic, "alpha", ref alphaInt))
				color.a = alphaInt / 255.0f;
			target.Tweener.TweenColor(color, easeType, time / 1000.0f);
			ActionList.Add(target.Tweener.GetTweenName(UTVPTweener.TWEEN_TYPE.Color));
		}
		
		target.Tweener.OnComplete = OnActionComplete;
	}
	
	public void OnActionComplete(string actionName)
	{
		ActionList.Remove(actionName);
		UKagSystem.Instance.conductor.Trigger("_action_" + actionName);
	}
	
	private bool Str2Number(Dictionary<string, string> paramDic, string key, ref int value)
	{
		if (!paramDic.ContainsKey(key))
			return false;
		return m_System.Str2Number(paramDic[key], ref value);
	}
	private bool Str2Number(Dictionary<string, string> paramDic, string key, ref float value)
	{
		if (!paramDic.ContainsKey(key))
			return false;
		return m_System.Str2Number(paramDic[key], ref value);
	}
}
